<?php
/*
 * This file is part of MVD_GUI.
 *
 *  MVD_GUI is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MVD_GUI is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MVD_GUI.  If not, see <http://www.gnu.org/licenses/>.
 *  Copyright 2010 Desmond Schmidt
 */
 
defined( '_JEXEC' ) or die( 'Restricted access' );
 
jimport( 'joomla.application.component.view');
 
/**
 * Edit view class for the MVD Component
 */
 
class MvdViewMvdedit extends JView
{
	public $text;
	public $vt;
	public $version;
	public $name;
	public $match;
	public $textLen;
	/** adjustments to offsets for selections taking account 
	  of entities */
	public $adjustments;
	public $offsets;
	/**
	 * In this view the XML must be converted into an editable 
	 * representation within a textarea. Hence there is no  
	 * transformation into HTML.
	 * @param xml the untransformed raw XML from nmerge
	 * @param versionId the version id
	 * @param name the name of the mvd
	 * @param vt the version table for this mvd
 	 */
	function setText( $xml, $versionId, $name, $vt )
	{
		$this->vt = $vt;
		$this->version = $versionId;
		$this->name = $name;
		$this->adjustments = array();
		$this->offsets = array();
		$this->text = $this->escape( $xml );
	}
	/**
	 * Set the current match. Adjust the offset. Must call this 
	 * AFTER setText.
	 * @param match the latest match after search
 	 */
	function setMatch( $match )
	{
		$this->match = $match;
		$real_offset = $match->offset;
		for ( $i=0;$i<count($this->offsets);$i++ )
		{
			if ( $this->offsets[$i] < $match->offset )
				$real_offset = $match->offset - $this->adjustments[$i];
		}
		$match->offset = $real_offset;
	}
	/**
	 * Convert every left and right angle bracket into their 
	 * escaped equivalents. Entities will be converted into single 
 	 * characters, which upsets the character offsets generated by 
	 * nmerge search. Build a table of offset-adjustments to compensate 
	 * for this.
	 * @param xml the input raw XML from the version
	 * @return the escaped XML for display
	 */
	function escape( &$xml )
	{
		$len = strlen( $xml );
		$state = 0;
		$text = "";
		for ( $i=0;$i<$len;$i++ )
		{
			if ( $xml[$i] == '<' )
				$text .= "&lt;";
			else if ( $xml[$i] == '>' )
				$text .= "&gt;";
			else if ( $xml[$i] == '&' )
			{
				// don't escape the ampersands at entity-start
				// all entities will be converted automatically
				// but do work out how much the offsets will 
				// be changed by them
				for ( $k=$i+1;$k<$len;$k++ )
				{
					if ( $xml[$k] == ';' )
					{
						$adjustments_len = count($this->adjustments);
						$previous = ($adjustments_len>0)?$this->adjustments[$adjustments_len-1]:0;
						$this->adjustments[] = $previous + ($k-$i);
						$this->offsets[] = $k+1;
						break;
					}
					else if ( $xml[$k] == ' ' )
						break;
				}
				$text .= $xml[$i];
			}
			else
				$text .= $xml[$i];
		}
		$this->textLen = $len;
		if ( count($this->adjustments)>0 )
			$this->textLen -= $this->adjustments[count($this->adjustments)-1];
		error_log("textLen=".$this->textLen);
		return $text;
	}
	/**
	 * Nothing special to do
 	 */
    function display($tpl = null)
    {
        parent::display($tpl);
    }
}
